package com.design.framework.aop;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import java.lang.reflect.Type;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.design.framework.annotion.SystemLog;
import com.design.framework.enums.SystemLogOperateEnums;
import com.design.framework.enums.SystemLogTypeEnums;

/**
 * 系统日志AOP
 * 
 * @author JohnDeng
 * @dateTime 2018年9月3日下午9:05:03
 */

public abstract class AbstractSystemLogAop {
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	

	@Pointcut("@annotation(com.design.framework.annotion.SystemLog)")
	public void sysLogPointcut() {
		
	}

	
	@Before("sysLogPointcut()")
	public void before(JoinPoint jp) throws Exception {
		logger.debug("------------------方法执行之前start------------------");
		logger.debug("------------------方法名：" + jp.getSignature().getName() + "------------------");
		logger.debug("------------------Class：" + jp.getSignature().getClass().getName() + "------------------");
		logger.debug("------------------DeclaringTypeName：" + jp.getSignature().getDeclaringTypeName()+ "------------------");
		logger.debug("------------------DeclaringType：" + jp.getSignature().getDeclaringType() + "------------------");
		logger.debug("------------------Modifiers：" + jp.getSignature().getModifiers() + "------------------");
		logger.debug("------------------方法执行之前end------------------");
	}

	

	@After("sysLogPointcut()")
	public void service(JoinPoint jp) throws Exception {
		doService(jp);
	}
	
	
	
	/**
	 * 主要写逻辑
	 * @author JohnDeng
	 * @dateTime 2019年5月30日上午10:26:29
	 * @param jp
	 */
	public abstract void doService(JoinPoint jp) throws Exception;
	
	
	
	/**
	 * 获取系统日志模块名称
	 * @author JohnDeng
	 * @dateTime 2019年4月10日下午2:22:59
	 * @param clazz
	 * @return
	 */
	public  String getSystemLogModelName(Class<?> clazz ) {
		SystemLog systemLog = clazz.getAnnotation(SystemLog.class);
		if (systemLog != null) {
			Method[] met = systemLog.annotationType().getDeclaredMethods();
			for (Method me : met) {
				if (!me.isAccessible()) {
					me.setAccessible(true);
				}
				try {
					if ("modelName".equals(me.getName())) {
						return (String) me.invoke(systemLog);
					}
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * 获取SysLog注解description
	 * 
	 * @param joinPoint
	 * @return
	 * @throws Exception
	 * @author John
	 * @dateTime 2017年12月1日下午12:17:22
	 */
	public String getMethodDescription(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class<?> targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		String description = "";
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class<?>[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					description = method.getAnnotation(SystemLog.class).description();
					break;
				}
			}
		}
		return description;
	}

	/**
	 * 获取SysLog注解operate
	 * 
	 * @param joinPoint
	 * @return
	 * @throws Exception
	 * @author John
	 * @dateTime 2017年12月1日下午12:17:02
	 */
	public SystemLogOperateEnums getMethodLogOperate(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class<?> targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		SystemLogOperateEnums operate = null;
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class<?>[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					operate = method.getAnnotation(SystemLog.class).operate();
					break;
				}
			}
		}
		return operate;
	}

	/**
	 * 获取SysLog注解媒体类型type
	 * 
	 * @param joinPoint
	 * @return
	 * @throws Exception
	 * @author JohnDeng 2018年12月15日上午12:21:33
	 */
	public SystemLogTypeEnums getMethodSystemLogType(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class<?> targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		SystemLogTypeEnums type = null;
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class<?>[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					type = method.getAnnotation(SystemLog.class).type();
					break;
				}
			}
		}
		return type;
	}

}
